package blingking.jfinal.orm.datasource;

import com.atomikos.jdbc.AtomikosDataSourceBean;
import blingking.jfinal.orm.xa.AtomikosDataSourceBeanBuilder;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;

import javax.sql.DataSource;
import javax.sql.XADataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Logger;
/**
 * @author King
 * @description
 * @Date 2020/3/22
 */
public class JFinalORMDataSource extends HashMap<String, DataSource> implements DataSource {
    public static final String DATASOURCE_NAME = "jFinalORMDataSource";
    private static volatile JFinalORMDataSource instance;

    public static JFinalORMDataSource getInstance() {
        if (instance == null) {
            synchronized (JFinalORMDataSource.class) {
                if (instance == null) {
                    instance = new JFinalORMDataSource();
                }
            }

        }
        return instance;
    }


    public JFinalORMDataSource build(Map<String, DataSourceProperties> dataSourcePropertiesMap) {
        dataSourcePropertiesMap.forEach((k, v) -> {
            DataSource dataSource = v.initializeDataSourceBuilder().build();
            if (dataSource instanceof XADataSource) {
                AtomikosDataSourceBean atomikosDataSourceBean = AtomikosDataSourceBeanBuilder.generBean(k).properties(initProperties(v)).build(dataSource);
                instance.put(k, atomikosDataSourceBean);
            } else {
                instance.put(k, dataSource);
            }
        });
        return instance;
    }

    private Properties initProperties(DataSourceProperties dataSourceProperties) {
        Properties properties = new Properties();
        properties.put("url", dataSourceProperties.getUrl());
        properties.put("user", dataSourceProperties.getUsername());
        properties.put("password", dataSourceProperties.getPassword());
        return properties;
    }


    @Override
    public Connection getConnection() throws SQLException {
        throw new RuntimeException("Un Support getConnection Method");
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        throw new RuntimeException("Un Support getConnection Method");
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        throw new RuntimeException("Un Support unwrap Method");
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        throw new RuntimeException("Un Support isWrapperFor Method");
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        throw new RuntimeException("Un Support getLogWriter Method");
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {
        throw new RuntimeException("Un Support setLogWriter Method");
    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {
        throw new RuntimeException("Un Support setLoginTimeout Method");
    }

    @Override
    public int getLoginTimeout() throws SQLException {
        throw new RuntimeException("Un Support getLoginTimeout Method");
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        throw new RuntimeException("Un Support getParentLogger Method");
    }

}
